/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import delaunay_triangulation.Delaunay_Triangulation;
import delaunay_triangulation.Point_dt;
import delaunay_triangulation.Triangle_dt;
import java.util.Iterator;
import java.util.Random;

/**
 *
 * @author Thiago
 */
public class MalhaTriangularIrregular {

    //Constantes da malha
    private final int QDE_INTERVALOS = 10;

    //Atributos da classe
    private Point_dt[] pontos;
    private Iterator<Triangle_dt> triangulos;
    private int numeroPontos;
    private int dimensao;
    private int altura;
    private boolean[] vetor;

    //Construtor personalizável
    public MalhaTriangularIrregular(int numeroPontos, int dimensao, int altura) {
        this.numeroPontos = numeroPontos;
        this.dimensao = dimensao;
        this.altura = altura;
    }

    //Construtor padrao
    public MalhaTriangularIrregular() {
        this.numeroPontos = 250;
        this.dimensao = 800;
        this.altura = 50;
    }

    public int getDimensao() {
        return dimensao;
    }

    public Iterator<Triangle_dt> getIterator() {
        if (this.pontos != null) {
            return new Delaunay_Triangulation(this.pontos).trianglesIterator();
        } else {
            return triangulos;
        }
    }

    //Gera malha com os valores padrões da classe
    public void gerarMalha() {
        geraMalha(this.numeroPontos, this.dimensao, this.altura);
    }

    //Gera malha com os valores personalizados pelo usuário
    public void gerarMalha(int numeroPontos, int dimensao, int altura) {
        geraMalha(numeroPontos, dimensao, altura);
    }

    private void geraMalha(int numeroPontos, int dimensao, int altura) {
        Point_dt[] pontosLocais = new Point_dt[numeroPontos];
        int ind = 0;
        Random gerador = new Random();
        int tamanhoIntervalo = dimensao / this.QDE_INTERVALOS;
        pontosLocais[ind++] = new Point_dt(0, 0, gerador.nextInt(altura));  //Ponto 0,0
        for (int i = 1; i < this.QDE_INTERVALOS; i++) {
            pontosLocais[ind++] = new Point_dt(0, i * tamanhoIntervalo, gerador.nextInt(altura)); //Gera os pontos fixos na primeira coluna
            pontosLocais[ind++] = new Point_dt(i * tamanhoIntervalo, 0, gerador.nextInt(altura)); //Gera os pontos fixos na primeira linha
        }
        for (int i = 0; i <= this.QDE_INTERVALOS; i++) {
            pontosLocais[ind++] = new Point_dt(i * tamanhoIntervalo, dimensao - 1, gerador.nextInt(altura)); //Gera os pontos fixos na ultima coluna
            pontosLocais[ind++] = new Point_dt(dimensao - 1, i * tamanhoIntervalo, gerador.nextInt(altura)); //Gera os pontos fixos na ultima linha
        }

        for (int i = ind; i < numeroPontos; i++) {
            pontosLocais[i] = new Point_dt(gerador.nextInt(dimensao), gerador.nextInt(dimensao), gerador.nextInt(altura));  //Gera os pontos aleatórios no interior da malha
        }

        this.pontos = pontosLocais;
    }

    public double[][] getMatriz() {
        int tamanho = 0;
        for (Iterator it1 = getIterator(); it1.hasNext();) {
            tamanho++;
            it1.next();
        }

        double[][] matriz = new double[4][tamanho * 3];
        this.vetor = new boolean[tamanho * 3];
        int ind = 0;
        for (Iterator it = getIterator(); it.hasNext();) {
            Triangle_dt atual = (Triangle_dt) it.next();
            //Joga o ponto 1 para a matriz
            if (atual.p1() != null) {
                matriz[0][ind] = atual.p1().x();
                matriz[1][ind] = atual.p1().y();
                matriz[2][ind] = atual.p1().z();
                this.vetor[ind++] = true;
            } else { //Se ele não existir, coloca 0 em toda a matriz
                matriz[0][ind] = 0;
                matriz[1][ind] = 0;
                matriz[2][ind] = 0;
                this.vetor[ind++] = false;
            }
            //Joga o ponto 2 para a matriz
            if (atual.p2() != null) {
                matriz[0][ind] = atual.p2().x();
                matriz[1][ind] = atual.p2().y();
                matriz[2][ind] = atual.p2().z();
                this.vetor[ind++] = true;
            } else { //Se ele não existir, coloca 0 em toda a matriz
                matriz[0][ind] = 0;
                matriz[1][ind] = 0;
                matriz[2][ind] = 0;
                this.vetor[ind++] = false;
            }
            //Joga o ponto 3 para a matriz
            if (atual.p3() != null) {
                matriz[0][ind] = atual.p3().x();
                matriz[1][ind] = atual.p3().y();
                matriz[2][ind] = atual.p3().z();
                this.vetor[ind++] = true;
            } else { //Se ele não existir, coloca 0 em toda a matriz
                matriz[0][ind] = 0;
                matriz[1][ind] = 0;
                matriz[2][ind] = 0;
                this.vetor[ind++] = false;
            }
        }
        return matriz;
    }

    public void setValores(int numeroPontos, int dimensao, int altura) {
        this.altura = altura;
        this.dimensao = dimensao;
        this.numeroPontos = numeroPontos;
    }

    public boolean[] getVetor() {
        return vetor;
    }
}
